package core.lib.model;

import java.util.Vector;

import core.lib.CoreConstants;
import core.lib.CoreEventDispatcher;
import core.lib.CoreRequestDispatcher;
import core.lib.interfaces.ICRequestHandler;
import core.lib.tools.CoreLog;

/**
 * <b><font color="red">客户端不使用。</font></b><br>
 * 抽象类。<code>Module</code>的子类可以被认为是一个模块的负责人，负责处理本<code>Module</code>与其他<code>Module</code>的交互。
 * 子类包中的其他类应该不能与其他包中的类交互，以降低包与包的耦合性。 <code>Module</code>之间传递的消息是<code>Request</code>，所以
 * <code>Module</code>类也实现<code>RequestHandler</code>接口。 <code>Module</code>的生命周期应该存在于整个软件的生命周期中，
 * <code>Module</code>的状态由自己维护。
 * 
 * @author <a href="mailto:cu2oh2co3@263.net">Ryan</a>
 */
public abstract class Module extends Thread implements ICRequestHandler
{
	public static final int EXIT_ABNORMAL = 2;
	public static final int EXIT_NORMAL = 1;
	public static final int EXIT_UNKNOWN = 0;

	public static final int LOG_ALL = 0;
	public static final int LOG_EXCEPTION_ONLY = 1;

	public static final int MODULE_STATE_OFF = 0;
	public static final int MODULE_STATE_ON = 1;
	public static final int MODULE_STATE_PAUSED = 2;

	private int m_exitCode = EXIT_UNKNOWN;
	private Vector<CoreRequest> m_requestPool;
	private int m_state = MODULE_STATE_ON;
	private final CoreRequestDispatcher mRequestDispatcher;
	private final CoreEventDispatcher mCoreEventDispatcher;

	// private LogAgent mLogAgent;

	protected Module(CoreRequestDispatcher reqDispatcher, CoreEventDispatcher eventDispatcher)
	{
		mRequestDispatcher = reqDispatcher;
		mCoreEventDispatcher = eventDispatcher;
		m_requestPool = new Vector<CoreRequest>(3); // 初始一个较合理的值。
	}

	/**
	 * 获取当前<code>Module</code>的状态
	 * 
	 * @return 当前<code>Module</code>的状态
	 */
	public int getModuleState()
	{
		return m_state;
	}

	public final void handleRequest(CoreRequest req)
	{
		synchronized (m_requestPool)
		{
			m_requestPool.addElement(req);
			m_requestPool.notify();
		}
	}

	/**
	 * <code>Module</code>线程的run方法。循环处理<code>Request</code>队列中的请求
	 * 
	 * @see java.lang.Thread#run()
	 */
	public void run()
	{
		try
		{
			CoreRequest req = null;

			while (m_state != MODULE_STATE_OFF)
			{
				try
				{
					// 如果有未处理完的Request，继续处理该Request
					// TODO: 可以给Request加上处理次数的Counter，规定最大重试次数
					if (req == null)
					{
						// 独占m_requestPool
						synchronized (m_requestPool)
						{
							if (m_requestPool.size() == 0)
							{
								m_requestPool.wait();
								continue;
							}
							else
							{
								req = (CoreRequest) m_requestPool.elementAt(0);
								m_requestPool.removeElementAt(0);
							}
						}
					}
					// 释放m_requestPool，然后处理Request
					doHandleRequest(req);
					req = null;
				}
				catch (InterruptedException ie)
				{
					CoreLog.log(CoreLog.LEVEL_ERROR, CoreConstants.CORE_TAG, "The module thread is interrupted");
					// 如果取到了Request并且未处理完，则继续处理
				}
				catch (Exception e)
				{
					CoreLog.log(CoreLog.LEVEL_ERROR, CoreConstants.CORE_TAG, e.toString());
					req = null;
				}
			}

			m_exitCode = doDestroy();

			if (m_exitCode == EXIT_NORMAL)
			{
				CoreLog.log(CoreLog.LEVEL_ERROR, CoreConstants.CORE_TAG, "The module thread has been destroyed successfully!");
			}
			else
			{
				CoreLog.log(CoreLog.LEVEL_ERROR, CoreConstants.CORE_TAG, "The module thread has been destroyed abnormally!");
			}
		}
		catch (Exception e)
		{
			CoreLog.log(CoreLog.LEVEL_ERROR, CoreConstants.CORE_TAG, "Root exception on THREAD#3", e);
		}
		catch (Error e)
		{
			CoreLog.log(CoreLog.LEVEL_ERROR, CoreConstants.CORE_TAG, "Root error on THREAD#3", e);
			e.printStackTrace();
		}
	}

	/**
	 * 退出前清理，返回清理结果。结果包括以下类型：
	 * <ul>
	 * <li>{@link #EXIT_UNKNOWN EXIT_UNKNOWN}</li>
	 * 未被清理
	 * <li>{@link #EXIT_NORMAL EXIT_NORMAL}</li>
	 * 清理成功
	 * <li>{@link #EXIT_ABNORMAL EXIT_ABNORMAL}</li>
	 * 清理中出现错误
	 * </ul>
	 * 
	 * @return 清理结果
	 */
	protected abstract byte doDestroy();

	/**
	 * 真正处理一个<code>Request</code>。
	 * 
	 * @param req
	 *            要处理的<code>Request</code>
	 */
	protected abstract void doHandleRequest(CoreRequest req);

	/**
	 * 向<code>Logger Module</code>添加一条Log记录抛出的<code>Exception</code>。
	 * 
	 * <strong>注意:</strong> 仅在<code>Polish</code>的<code>debug</code>开关打开时运行。
	 * 
	 * @param c
	 *            事件发生的Class
	 * @param e
	 *            事件伴随的Exception
	 */
	// protected void log(Exception e)
	// {
	// if (mLogAgent != null)
	// {
	// mLogAgent.addLog(getClass(), e);
	// }
	// }

	/**
	 * 除非当前设置只记录抛出的异常，否则向<code>Logger Module</code> 添加一条Log记录记录一段消息。
	 * 
	 * <strong>注意:</strong> 仅在<code>Polish</code>的<code>debug</code>开关打开时运行。
	 * 
	 * @param c
	 *            事件发生的Class
	 * @param s
	 *            事件消息
	 */
	// protected void log(String s)
	// {
	// if (mLogAgent != null)
	// {
	// mLogAgent.addLog(getClass(), s);
	// }
	// }

	protected synchronized void setState(int state)
	{
		m_state = state;
	}

	/**
	 * 取消当前所有排队的请求
	 */
	protected void clearRequestPool()
	{
		synchronized (m_requestPool)
		{
			CoreRequest req;
			for (int i = m_requestPool.size() - 1; i >= 0; i--)
			{
				req = (CoreRequest) m_requestPool.elementAt(i);
				if (req != null)
				{
					req.setResponse(CoreConstants.RequestReturnCode.FATAL_ERROR, null);
				}
			}
			m_requestPool.removeAllElements();
		}
	}

	protected void sendCoreRequest(CoreRequest req)
	{
		if (mRequestDispatcher != null)
		{
			mRequestDispatcher.sendCoreRequest(req);
		}
	}

	protected void triggerCoreEvent(CoreEvent event)
	{
		if (mCoreEventDispatcher != null)
		{
			mCoreEventDispatcher.handleCoreEvent(event);
		}
	}

	// public void setLogAgent(LogAgent logAgent)
	// {
	// mLogAgent = logAgent;
	// }

	public void finalize()
	{
		m_state = MODULE_STATE_OFF;
		interrupt();
	}
}